/**
  ******************************************************************************
  * @file    DPC_Miscellaneous.c
  * @author  STMicroelectronics
  * @date    09-June-2022
  * @brief   This file contains functions definitions for LED and Keys Control usage
  ******************************************************************************
  *
  * @copyright (c) 2021(-2022) Biricha Digital Power Limited
  * @copyright (c) 2022(-2023) STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file in
  * the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  ******************************************************************************
  *
  */

/** @addtogroup STM32_DPOW
  * @brief  Digital Power application implemented with a STM32 MCU
  * @{
  */
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
#include "DPC_Miscellaneous.h"
#ifdef STM32F334x8
#include "stm32f3xx_hal_gpio.h"
#elif STM32G474xx
#include "stm32g4xx_hal_gpio.h"
#else
  #error CPU  not specified
#endif

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* External variables --------------------------------------------------------*/
/* External functions --------------------------------------------------------*/
/** @addtogroup LED_Management
  * @{
  */
/**
  * @brief  Turns user LED On.
  * @param  pLED : Pointer to LED object
  * @retval None
  */
void UserLEDOn(LED_Status_t* pLED)
{
  HAL_GPIO_WritePin(pLED->GPIOx, pLED->GPIO_Pin, GPIO_PIN_SET);
  pLED->bActualOn = true;
}

/**
  * @brief  Turns user LED Off.
  * @param  pLED : Pointer to LED object
  * @retval None
  */
void UserLEDOff(LED_Status_t* pLED)
{
  HAL_GPIO_WritePin(pLED->GPIOx, pLED->GPIO_Pin, GPIO_PIN_RESET);
  pLED->bActualOn = false;
}

/**
  * @brief  Toggle user LED.
  * @param  pLED : Pointer to LED object
  * @retval None
  */
void UserLEDToggle(LED_Status_t* pLED)
{
  HAL_GPIO_TogglePin(pLED->GPIOx, pLED->GPIO_Pin);
  pLED->bActualOn = (bool)(1 - pLED->bActualOn);
}

/**
  * @brief  Sets params of LED status.
  * @param  pLED : Pointer to LED object
  * @param  newLEDModality : new LED modality, a value of LED_Modality_t
  * @param  nBlinkCounter  : number of blinking in LED_BLINK_N modality
  * @param  hBlinkPeriodms : blinking period in LED_BLINK_N modality
  * @param  hhBlinkRepetitionPeriodms : blinking repetition period in LED_BLINK_N modality (stop period before a blink again nBlinkCounter times)
  * @retval None
  */
void LED_SetParams(LED_Status_t* pLED, LED_Modality_t newLEDModality, uint8_t nBlinkCounter, uint16_t hBlinkPeriodms, uint16_t hhBlinkRepetitionPeriodms)
{
  pLED->LED_Modality = newLEDModality;
  pLED->nBlinkCount = nBlinkCounter;
  pLED->nBlinkLeftCount = nBlinkCounter;
  pLED->hBlinkPeriodms = hBlinkPeriodms;
  pLED->hBlinkPeriodCounterLeft = hBlinkPeriodms;
  pLED->hBlinkRepetitionPeriodms = hhBlinkRepetitionPeriodms;
}

/**
  * @brief  Decreases LED's blinking counter.
  * @param  pLED : Pointer to LED object
  * @retval None
  */
void LED_DecreaseBlinkCounter(LED_Status_t* pLED)
{
  if((pLED->hBlinkPeriodCounterLeft != 0)) pLED->hBlinkPeriodCounterLeft--;
}

/**
  * @brief  Manages LED's blinking and ON/OFF.
  * @param  pLED : Pointer to LED object
  * @retval None
  */
void LED_Task(LED_Status_t* pLED)
{
  switch(pLED->LED_Modality)
  {
  default:
  case LED_OFF:
    if(pLED->bActualOn == true)
    {
      UserLEDOff(pLED);
    }
    break;

  case LED_ON:
    if(pLED->bActualOn == false)
    {
      UserLEDOn(pLED);
    }
    break;

  case LED_BLINK_N:
    if((pLED->hBlinkPeriodCounterLeft == 0) && (pLED->nBlinkLeftCount != 0))
    {
      if(pLED->bActualOn == true)
      {
        UserLEDOff(pLED);
        pLED->nBlinkLeftCount--;
      }
      else
      {
        UserLEDOn(pLED);
      }
      pLED->hBlinkPeriodCounterLeft = pLED->hBlinkPeriodms;
    }
    else if(pLED->nBlinkLeftCount == 0)
    { // Reenable blinking after hBlinkRepetitionPeriodms ms
      pLED->nBlinkLeftCount = pLED->nBlinkCount;
      pLED->hBlinkPeriodCounterLeft = pLED->hBlinkRepetitionPeriodms;
    }
    break;

  case LED_BLINK_INF:
    if(pLED->hBlinkPeriodCounterLeft == 0)
    { // Toggle and reload blinking period
      UserLEDToggle(pLED);
      pLED->hBlinkPeriodCounterLeft = pLED->hBlinkPeriodms;
    }
    break;
  }
}
/**
  * @} end LED_Management
  */


/** @addtogroup BUTTON_Management
  * @{
  */
/** @brief Detect a key press
  * @details
  * This detects a key press and return true. We also have debounce, so we must detect a
  * falling edge before waiting for a rising edge.
  * @param  pKEY : Pointer to user's button object
  * @retval Return TRUE if the key has been pressed, FALSE otherwise
  */
bool KeyDebounce(KEY_DEBOUNCE_t *pKEY)
{
  bool value = false;

  if (0 == HAL_GetTick() % 128)
  {
    if (HAL_GPIO_ReadPin(pKEY->GPIOx, pKEY->GPIO_Pin) == GPIO_PIN_SET)
    {
      if (pKEY->m_State == false)
      {
        value = true;
      }
      pKEY->m_State = true;
    }
    else
    {
      pKEY->m_State = false;
    }
  }
  return value;
}
/**
  * @} end BUTTON_Management
  */

/** @addtogroup LOAD_Management
  * @{
  */
/**
  * @} end LOAD_Management
  */

/**
  * @} end STM32_DPOW
  */
